import { Injectable } from '@nestjs/common';
import {
  ConnectedSocket,
  MessageBody,
  SubscribeMessage,
  WebSocketGateway,
} from '@nestjs/websockets';
import { ChatService } from 'src/chat/chat.service';
import * as WebSocket from 'ws';
import { Types } from 'mongoose';
import wsMap, { WsEvent } from './ws.container';
import {
  AddFriendSendMessage,
  ChatSendMessage,
  ChatSendType,
  DealWithAddFriendSendMessage,
} from './packet.interface';
import { TaskType } from 'src/schemas/user.schema';
import {
  AddFriendWsResFailData_1,
  AddFriendWsResFailData_2,
  AddFriendWsResSuccData,
  ChatSendWsResFailData,
  ChatSendWsResFailData_1,
  ChatSendWsResSuccData,
  DealWithAddFriendWsResFailData,
  DealWithAddFriendWsResSuccData,
} from './response.interface';

@WebSocketGateway(3002)
@Injectable()
export class WsStartGateway {
  constructor(private chatService: ChatService) {}

  @SubscribeMessage(WsEvent.SEND_MESSAGE)
  async sendPeivate(
    @MessageBody() data: any,
    @ConnectedSocket() client: WebSocket,
  ): Promise<any> {
    const myId = client['__id__'];
    if (!myId) {
      return new ChatSendWsResFailData();
    }
    const { id: goalId, text, type } = data;
    if (type !== ChatSendType.PRIVATE_CHAT) {
      return new ChatSendWsResFailData();
    }
    const result = await this.chatService.sendPrivate(
      {
        text,
        time: '昨天',
      },
      new Types.ObjectId(myId),
      new Types.ObjectId(goalId),
    );
    if (result.code === 1) {
      return new ChatSendWsResFailData_1();
    }
    if (result.code === 0) {
      if (wsMap.has(goalId)) {
        const sendData: ChatSendMessage = {
          event: WsEvent.SEND_MESSAGE,
          type: 0,
          data: {
            user_id: myId,
            id: result.anyoneRecordsItemId.toHexString(),
            text,
            time: '昨天',
          },
        };
        wsMap.get(goalId).send(JSON.stringify(sendData));
      }
      // 返回这条消息在消息记录中的唯一id
      return new ChatSendWsResSuccData(
        result.myselfRecordsItemId.toHexString(),
      );
    }
    return new ChatSendWsResFailData();
  }

  @SubscribeMessage(WsEvent.SEND_TASK)
  async addFriend(
    @MessageBody() data: any,
    @ConnectedSocket() client: WebSocket,
  ): Promise<any> {
    const myId = client['__id__'];
    if (!myId) {
      return;
    }
    const { id: goal_id } = data;
    // 检查是否重复发送，如果不是重复发送，将添加好友的信息添加到对方任务处理栈。
    const result = await this.chatService.friendRequest(
      new Types.ObjectId(myId),
      new Types.ObjectId(goal_id),
    );
    // 返回为真值，表示成功了。
    if (result.code === 0) {
      // 判断对方是否在线
      if (wsMap.has(goal_id)) {
        const sendRes: AddFriendSendMessage = {
          event: WsEvent.SEND_TASK,
          type: TaskType.ADD_FRIEND,
          data: {
            id: myId,
          },
        };
        wsMap.get(goal_id).send(JSON.stringify(sendRes));
      }
      return new AddFriendWsResSuccData();
    } else if (result.code === 1) {
      return new AddFriendWsResFailData_1();
    } else if (result.code === 2) {
      return new AddFriendWsResFailData_2();
    }
  }

  @SubscribeMessage(WsEvent.SEND_TASK)
  async dealWithAddFriend(
    @MessageBody() data: any,
    @ConnectedSocket() client: WebSocket,
  ): Promise<any> {
    const myId = client['__id__'];
    if (!myId) {
      return;
    }
    const { id: goal_id, agreed } = data;
    const result = await this.chatService.dealWithAddFriendRequest(
      new Types.ObjectId(myId),
      new Types.ObjectId(goal_id),
      agreed,
    );
    if (result.code === 0) {
      // 判断对方是否在线
      if (wsMap.has(goal_id)) {
        const sendRes: DealWithAddFriendSendMessage = {
          event: WsEvent.SEND_TASK,
          type: TaskType.DEAL_WITH_ADD_FRIEND,
          data: {
            id: myId,
            agreed,
          },
        };
        wsMap.get(goal_id).send(JSON.stringify(sendRes));
      }
      return new DealWithAddFriendWsResSuccData();
    }
    return new DealWithAddFriendWsResFailData();
  }
}
